package com.bjjnts.service;

import cn.hutool.core.img.Img;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.Resource;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.bjjnts.code.CaptchaUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.awt.*;
import java.io.File;
import java.util.List;
import java.util.*;

@Slf4j
public class WatchService {

    @Getter
    private String userName;

    @Getter
    private String password;

    @Setter
    private String facePath;

    private WatchService(){}

    public WatchService(String userName, String password) {
        this.userName = userName;
        this.password = password;
    }

    private Dict cacheDict = new Dict();

    /**
     * 登录
     *
     * @param username
     * @param password
     */
    public JSONObject login(String username, String password) {
        String url = "https://apif.bjjnts.cn/account/login";

        Map<String, String> headers = getCommonHeaderMap();
        headers.put("Referer", "https://www.bjjnts.cn/user/login");

        JSONObject params = new JSONObject();
        params.set("username", username);
        params.set("password", password);
        params.set("type", 1);

        String loginUserStr =
                HttpRequest.post(url).headerMap(headers, true).body(JSONUtil.toJsonStr(params)).execute().body();
        log.info("登录成功" + loginUserStr);
        JSONObject loginUser = JSONUtil.parseObj(loginUserStr);
        cacheDict.set("userInfo", loginUser);
        return loginUser;
    }

    /**
     * 获取课程列表
     *
     * @return
     */
    public JSONArray getCourseList() {
        String url = "https://apif.bjjnts.cn/student-center/study";

        Map<String, String> headers = getCommonHeaderMap();
        headers.put("Referer", "https://www.bjjnts.cn/mine/student/study");
        headers.put("Authorization", "Bearer " + getToken());

        String respBody = HttpRequest.get(url).headerMap(headers, true).execute().body();
        JSONObject respJson = JSONUtil.parseArray(respBody).getJSONObject(0);
        return respJson.getJSONArray("courseMap");
    }

    /**
     * 获取单元列表
     *
     * @param class_id
     *            班级id
     * @param course_id
     *            课程id
     */
    public JSONArray getUnitList(String class_id, String course_id) {
        String url = "https://apif.bjjnts.cn/courses/test-preview?course_id=" + course_id + "&class_id=" + class_id;

        Map<String, String> headers = getCommonHeaderMap();
        headers.put("Referer", "https://www.bjjnts.cn/study?course_id=" + course_id + "&class_id=" + class_id);
        headers.put("Authorization", "Bearer " + getToken());

        String body = HttpRequest.get(url).headerMap(headers, true).execute().body();

        return JSONUtil.parseObj(body).getJSONArray("course");
    }

    /**
     * 获得单元详情
     * @param class_id
     * @param course_id
     * @param unit_id
     */
    public JSONObject getUnitInfo(String class_id, String course_id, String unit_id) {
        String url = "https://apif.bjjnts.cn/course-units/" + unit_id + "?class_id=" + class_id;

        Map<String, String> headers = getCommonHeaderMap();
        headers.put("Referer", "https://www.bjjnts.cn/study?course_id="+ course_id +"&class_id="+ class_id +"&unit_id=" + unit_id);
        headers.put("Authorization", "Bearer " + getToken());

        String body = HttpRequest.get(url).headerMap(headers, true).execute().body();
        return JSONUtil.parseObj(body);
    }

    /**
     *
     * @param class_id
     * @param course_id
     * @param unit_id
     * @param video_id
     * @param time
     * @param is_end
     */
    public JSONObject studies(String class_id, String course_id, String unit_id, String video_id, int time, boolean is_end) throws Exception {
        String url = "https://apif.bjjnts.cn/studies?video_id=" + video_id + "&u=" + getInfo().getStr("id") + "&time=" + time + "&unit_id=" + unit_id + "&class_id=" + class_id;
        if (time == 0) {
            url = url + "&start=1";
        }
        if(is_end) {
            url = url + "&end=1";
        }

        Map<String, String> headers = getCommonHeaderMap();
        headers.put("Referer", "https://www.bjjnts.cn/study/video?class_id=" + class_id + "&course_id=" + course_id + "&unit_id=" + unit_id);
        headers.put("Authorization","Bearer " + getToken());
        String body = HttpRequest.post(url).headerMap(headers, true).execute().body();
        if (StrUtil.isNotBlank(body) && (!StrUtil.equals(body, "null"))) {
            log.info("body=" + body);
            JSONObject rep = JSONUtil.parseObj(body);
            Integer code = rep.getInt("code");
            // 验证码识别
            if (code == 2002) {
                String code1 = this.code(class_id, course_id, unit_id);
                this.smart(class_id, course_id, unit_id, code1);
            }
            // 人脸识别
            if (code == 2003) {
                this.face(class_id, course_id, unit_id);
            }
            return rep;
        }
        return new JSONObject();
    }

    public String code(String class_id, String course_id, String unit_id) throws Exception {
        String url = "https://apif.bjjnts.cn/supervises/code";

        Map<String, String> headers = getCommonHeaderMap();
        headers.put("Referer", "https://www.bjjnts.cn/study/video?class_id=" + class_id + "&course_id=" + course_id + "&unit_id=" + unit_id);
        headers.put("Authorization", "Bearer " + getToken());

        String imageBase64 = HttpRequest.get(url).headerMap(headers, true).execute().body();
        JSONObject codeRep = CaptchaUtil.verifyCode(imageBase64);
        return codeRep.getStr("result");
    }

    public void smart(String class_id, String course_id, String unit_id, String code) {
        String url = "https://apif.bjjnts.cn/supervises/smart-new";

        Map<String, String> headers = getCommonHeaderMap();
        headers.put("Referer", "https://www.bjjnts.cn/study/video?class_id=" + class_id + "&course_id=" + course_id + "&unit_id=" + unit_id);
        headers.put("Authorization", "Bearer " + getToken());

        JSONObject params = new JSONObject();
        params.set("code", code);
        params.set("course_id", course_id);
        params.set("unit_id", unit_id);
//        params.set("class_id", class_id);
        log.info("------进行验证码识别------");
        String body = HttpRequest.post(url).headerMap(headers, true).body(JSONUtil.toJsonStr(params)).execute().body();
        log.info(body);
    }


    /**
     *  人脸识别
     * @param class_id
     * @param course_id
     * @param unit_id
     */
    public void face(String class_id, String course_id, String unit_id) throws Exception {
        Map<String, String> headers = getCommonHeaderMap();
        headers.put("Referer", "https://www.bjjnts.cn/study/video?class_id=" + class_id + "&course_id=" + course_id
                + "&unit_id=" + unit_id);
        headers.put("Authorization", "Bearer " + getToken());
        String url = "https://apif.bjjnts.cn/supervises";
        JSONObject json = new JSONObject();
        json.set("baseImage", getFace());
        json.set("course_id", course_id);
        json.set("unit_id", unit_id);
        json.set("class_id", class_id);
        log.info("------进行人脸识别------");
        String body = HttpRequest.post(url).headerMap(headers, true).body(JSONUtil.toJsonStr(json)).execute().body();
        if (StrUtil.containsAnyIgnoreCase(body, "失败")) {
            log.info("换个照片吧..");
            throw new Exception(body);
        }
        log.info(body);
    }

    public String getFace() {
        Font font = new Font(Font.DIALOG, Font.PLAIN, 10);
        String path = "face";
        if (StrUtil.isNotBlank(this.facePath)) {
            path = this.facePath;
        }
        Resource resourceObj = ResourceUtil.getResourceObj(path+ File.separator + this.userName + ".jpg");
        int content = RandomUtil.randomInt(0, 30);
        int x = RandomUtil.randomInt(0, 287);
        int y = RandomUtil.randomInt(0, 287);
        Img img = Img.from(FileUtil.file(resourceObj.getUrl())).pressText(content + "", Color.white,
                font, x, y, 1.0F).rotate(content);
        return ImgUtil.toBase64(img.getImg(), "jpg");
    }

    public JSONObject getInfo() {
        JSONObject userInfo = (JSONObject) this.cacheDict.get("userInfo");
        if (userInfo != null && userInfo.containsKey("access_token")) {
            return userInfo;
        }
        return login(this.userName, this.password);
    }

    public String getToken() {
        return this.getInfo().getStr("access_token");
    }

    public List<JSONObject> getTaskList() {
        log.info("--------getTaskList-------");
        List<JSONObject> list = new ArrayList<>();
        JSONArray courseList = this.getCourseList();

        for (int j = 0; j< courseList.size(); j ++) {
            JSONObject o = courseList.getJSONObject(j);
            String class_id = o.getStr("class_id");
            String course_id = o.getStr("course_id");
            String course_name = o.getJSONObject("course").getStr("title");
            JSONArray unitList = getUnitList(class_id, course_id);
            for (int i = 0; i < unitList.size(); i++) {
                JSONObject course = unitList.getJSONObject(i);
//                System.out.println(JSONUtil.toJsonStr(course));
                String unit_name = course.getStr("title");
                Object unitsObj = course.get("units");
//                System.out.println(unitsObj);
                if (Objects.equals(unitsObj, null)) {
                    continue;
                }
                JSONArray units = course.getJSONArray("units");
                JSONObject unit = units.getJSONObject(0);
                String unit_id = unit.getStr("id");
                String title = unit.getStr("title");
                JSONObject unitInfo = getUnitInfo(class_id, course_id, unit_id);
                JSONObject study = new JSONObject();
                study.set("class_id", class_id);
                study.set("course_id", course_id);
                study.set("unit_id", unit_id);
                study.set("video_id", unitInfo.getStr("id"));
                study.set("time", unitInfo.getStr("total_time"));
                study.set("progress_time", unitInfo.getStr("progress_time"));
                //
                study.set("course_name", course_name + "-" + title);
                study.set("unit_name", unit_name);
                list.add(study);
            }
        }
        return list;
    }

    private Map<String, String> getCommonHeaderMap() {
        Map<String, String> headerMap = new HashMap<>();
        headerMap.put("Accept", "application/json, text/plain, */*");
        headerMap.put("Accept-Encoding", "gzip, deflate, br");
        headerMap.put("Accept-Language", "zh-CN,zh;q=0.9");
        headerMap.put("Connection", "keep-alive");
        headerMap.put("Content-Type", "application/json");
        headerMap.put("Host", "apif.bjjnts.cn");
        headerMap.put("Origin", "https://www.bjjnts.cn");
        headerMap.put("sec-ch-ua", "\"Google Chrome\";v=\"93\", \" Not;A Brand\";v=\"99\", \"Chromium\";v=\"93\"");
        headerMap.put("sec-ch-sec-ch-ua-mobile", "?0");
        headerMap.put("sec-ch-ua-platform", "\"Windows\"");
        headerMap.put("Sec-Fetch-Dest", "empty");
        headerMap.put("Sec-Fetch-Mode", "cors");
        headerMap.put("Sec-Fetch-Site", "same-site");
        headerMap.put("User-Agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36");
        headerMap.put("X-Client-Type", "pc");
        return headerMap;
    }

}
